package com.crpc.core.compress;

import com.crpc.core.compress.impl.GzipCompressor;
import com.crpc.core.compress.impl.LZ4Compressor;
import com.crpc.core.compress.impl.ZipCompressor;
import com.crpc.core.config.ObjectWrapper;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import static com.crpc.common.crpcEnum.CompressorEnums.*;

/**
 * @author wzy
 * @version 1.0
 * @description:
 * @date 2023/9/30 9:02
 */
@Slf4j
public class CompressorFactory {
    private static final ConcurrentHashMap<String, ObjectWrapper<CompressorWrapper>> COMPRESSOR_CACHE = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<Byte, ObjectWrapper<CompressorWrapper>> COMPRESSOR_CACHE_CODE = new ConcurrentHashMap<>();

    static {
        CompressorWrapper gzip = new CompressorWrapper(GZIP.getCode(), GZIP.getType(), new GzipCompressor());
        CompressorWrapper zip = new CompressorWrapper(ZIP.getCode(), ZIP.getType(), new ZipCompressor());
        CompressorWrapper lz4 = new CompressorWrapper(LZ4.getCode(), LZ4.getType(), new LZ4Compressor());
        ObjectWrapper<CompressorWrapper> gzipWrapper = new ObjectWrapper<>(GZIP.getCode(), GZIP.getType(), gzip);
        ObjectWrapper<CompressorWrapper> zipWrapper = new ObjectWrapper<>(ZIP.getCode(), ZIP.getType(), lz4);
        ObjectWrapper<CompressorWrapper> lz4Wrapper = new ObjectWrapper<>(LZ4.getCode(), LZ4.getType(), zip);
        COMPRESSOR_CACHE.put(GZIP.getType(), gzipWrapper);
        COMPRESSOR_CACHE.put(ZIP.getType(), zipWrapper);
        COMPRESSOR_CACHE.put(LZ4.getType(), lz4Wrapper);
        COMPRESSOR_CACHE_CODE.put(GZIP.getCode(), gzipWrapper);
        COMPRESSOR_CACHE_CODE.put(ZIP.getCode(), zipWrapper);
        COMPRESSOR_CACHE_CODE.put(LZ4.getCode(), lz4Wrapper);
    }

    public static CompressorWrapper getCompressor(String compressorType) {
        ObjectWrapper<CompressorWrapper> objectWrapper = COMPRESSOR_CACHE.get(compressorType);
        return objectWrapper != null ? objectWrapper.getObjectImpl() : COMPRESSOR_CACHE.get(GZIP.getType()).getObjectImpl();
    }

    public static CompressorWrapper getCompressor(byte compressorCode) {
        ObjectWrapper<CompressorWrapper> objectWrapper = COMPRESSOR_CACHE_CODE.get(compressorCode);
        return objectWrapper != null ? objectWrapper.getObjectImpl() : COMPRESSOR_CACHE_CODE.get(GZIP.getCode()).getObjectImpl();
    }

    //添加一个新压缩策略
    public static void addCompressorList(List<ObjectWrapper<Compressor>> objectWrapper) {
        for (ObjectWrapper<Compressor> wrapper : objectWrapper) {
            ObjectWrapper<CompressorWrapper> compressorWrapperObjectWrapper = new ObjectWrapper<>(wrapper.getObjectCode(), wrapper.getObjectType(), new CompressorWrapper(wrapper.getObjectCode(), wrapper.getObjectType(), wrapper.getObjectImpl()));
            COMPRESSOR_CACHE.put(wrapper.getObjectType(), compressorWrapperObjectWrapper);
            COMPRESSOR_CACHE_CODE.put(wrapper.getObjectCode(), compressorWrapperObjectWrapper);
        }
    }
}
